package com.s666.demo.exception;

import com.s666.demo.common.response.ResultVO;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
/**
 * 通用异常处理: 兜底
 * 程序会优先使用controller自行定制的异常(本项目指的是BaseController),
 * 若没有定制才会采用执行本类异常处理机制
 * @author lijin
 */
@ControllerAdvice
public class ExceptionResolver {

    @Autowired
    protected MessageRender messageRender;


    /**
     * 字段校验异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public ResultVO validExceptionHandler(BindException e) {
        CommonException ce = new CommonException("500", e.getMessage());
        return messageRender.json(ce);

    }


    @ExceptionHandler(value = JsonException.class)
    @ResponseBody
    public ResultVO jsonExceptionHandler(JsonException e) {
        return messageRender.json(e);
    }

    @ExceptionHandler(value = CommonException.class)
    @ResponseBody
    public ModelAndView commonExceptionHandler(CommonException e) {
        return messageRender.html(e);
    }

    /**
     * 通用异常处理类, 自动判断是否json
     * 捕获@RequestMapping注解的方法抛出的Exception异常并处理：
     * @param req
     * @param e
     * @throws Exception
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Object defaultErrorHandler(HttpServletRequest req, HttpServletResponse res, Exception e) {
        CommonException ce = new CommonException("500", e.getMessage());
        boolean hasJson = hasJson(req);
        if (hasJson) {
            return messageRender.json(ce);
        } else {
            return messageRender.html(ce);
        }
    }



    String isJsonStr = "application/json";
    String xmlReqStr = "XMLHttpRequest";
    /**
     * 判断是否json请求
     * @param req
     * @return
     */
    private boolean hasJson(HttpServletRequest req){
        String contentTypeHeader = req.getHeader("Content-Type");
        String acceptHeader = req.getHeader("Accept");
        String xRequestedWith = req.getHeader("X-Requested-With");

        if (contentTypeHeader != null && contentTypeHeader.contains(isJsonStr)){
            return true;
        }
        if(acceptHeader != null && acceptHeader.contains(isJsonStr)){
            return true;
        }

        if (xmlReqStr.equalsIgnoreCase(xRequestedWith) ) {
            return true;
        }
        return false;
    }
}
